<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!-- /fasttmp/mkdist-qt-4.3.5-1211793125/qtopia-core-opensource-src-4.3.5/doc/src/examples/application.qdoc -->
<head>
  <title>Qt 4.3: Application Example</title>
  <link href="classic.css" rel="stylesheet" type="text/css" />
</head>
<body>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td align="left" valign="top" width="32"><a href="http://www.trolltech.com/products/qt"><img src="images/qt-logo.png" align="left" width="32" height="32" border="0" /></a></td>
<td width="1">&nbsp;&nbsp;</td><td class="postheader" valign="center"><a href="index.html"><font color="#004faf">Home</font></a>&nbsp;&middot; <a href="classes.html"><font color="#004faf">All&nbsp;Classes</font></a>&nbsp;&middot; <a href="mainclasses.html"><font color="#004faf">Main&nbsp;Classes</font></a>&nbsp;&middot; <a href="groups.html"><font color="#004faf">Grouped&nbsp;Classes</font></a>&nbsp;&middot; <a href="modules.html"><font color="#004faf">Modules</font></a>&nbsp;&middot; <a href="functions.html"><font color="#004faf">Functions</font></a></td>
<td align="right" valign="top" width="230"><a href="http://www.trolltech.com"><img src="images/trolltech-logo.png" align="right" width="203" height="32" border="0" /></a></td></tr></table><h1 align="center">Application Example<br /><small></small></h1>
<p>Files:</p>
<ul>
<li><a href="mainwindows-application-mainwindow-cpp.html">mainwindows/application/mainwindow.cpp</a></li>
<li><a href="mainwindows-application-mainwindow-h.html">mainwindows/application/mainwindow.h</a></li>
<li><a href="mainwindows-application-main-cpp.html">mainwindows/application/main.cpp</a></li>
<li><a href="mainwindows-application-application-qrc.html">mainwindows/application/application.qrc</a></li>
</ul>
<p>The Application example shows how to implement a standard GUI application with menus, toolbars, and a status bar. The example itself is a simple text editor program built around <a href="qtextedit.html">QTextEdit</a>.</p>
<p align="center"><img src="images/application.png" alt="Screenshot of the Application example" /></p><p>Nearly all of the code for the Application example is in the <tt>MainWindow</tt> class, which inherits <a href="qmainwindow.html">QMainWindow</a>. <a href="qmainwindow.html">QMainWindow</a> provides the framework for windows that have menus, toolbars, dock windows, and a status bar. The application provides <b>File</b>, <b>Edit</b>, and <b>Help</b> entries in the menu bar, with the following popup menus:</p>
<p align="center"><img src="images/application-menus.png" alt="The Application example's menu system" /></p><p>The status bar at the bottom of the main window shows a description of the menu item or toolbar button under the cursor.</p>
<p>To keep the example simple, recently opened files aren't shown in the <b>File</b> menu, even though this feature is desired in 90% of applications. The <a href="mainwindows-recentfiles.html">Recent Files</a> example shows how to implement this. Furthermore, this example can only load one file at a time. The <a href="mainwindows-sdi.html">SDI</a> and <a href="mainwindows-mdi.html">MDI</a> examples shows how to lift these restrictions.</p>
<a name="mainwindow-class-definition"></a>
<h2>MainWindow Class Definition</h2>
<p>Here's the class definition:</p>
<pre> class MainWindow : public QMainWindow
 {
     Q_OBJECT

 public:
     MainWindow();

 protected:
     void closeEvent(QCloseEvent *event);

 private slots:
     void newFile();
     void open();
     bool save();
     bool saveAs();
     void about();
     void documentWasModified();

 private:
     void createActions();
     void createMenus();
     void createToolBars();
     void createStatusBar();
     void readSettings();
     void writeSettings();
     bool maybeSave();
     void loadFile(const QString &amp;fileName);
     bool saveFile(const QString &amp;fileName);
     void setCurrentFile(const QString &amp;fileName);
     QString strippedName(const QString &amp;fullFileName);

     QTextEdit *textEdit;
     QString curFile;

     QMenu *fileMenu;
     QMenu *editMenu;
     QMenu *helpMenu;
     QToolBar *fileToolBar;
     QToolBar *editToolBar;
     QAction *newAct;
     QAction *openAct;
     QAction *saveAct;
     QAction *saveAsAct;
     QAction *exitAct;
     QAction *cutAct;
     QAction *copyAct;
     QAction *pasteAct;
     QAction *aboutAct;
     QAction *aboutQtAct;
 };</pre>
<p>The public API is restricted to the constructor. In the <tt>protected</tt> section, we reimplement <a href="qwidget.html#closeEvent">QWidget::closeEvent</a>() to detect when the user attempts to close the window, and warn the user about unsaved changes. In the <tt>private slots</tt> section, we declare slots that correspond to menu entries, as well as a mysterious <tt>documentWasModified()</tt> slot. Finally, in the <tt>private</tt> section of the class, we have various members that will be explained in due time.</p>
<a name="mainwindow-class-implementation"></a>
<h2>MainWindow Class Implementation</h2>
<pre> #include &lt;QtGui&gt;

 #include &quot;mainwindow.h&quot;</pre>
<p>We start by including <tt>&lt;QtGui&gt;</tt>, a header file that contains the definition of all classes in the <a href="qtcore.html">QtCore</a> and <a href="qtgui.html">QtGui</a> libraries. This saves us from the trouble of having to include every class individually. We also include <tt>mainwindow.h</tt>.</p>
<p>You might wonder why we don't include <tt>&lt;QtGui&gt;</tt> in <tt>mainwindow.h</tt> and be done with it. The reason is that including such a large header from another header file can rapidly degrade performances. Here, it wouldn't do any harm, but it's still generally a good idea to include only the header files that are strictly necessary from another header file.</p>
<pre> MainWindow::MainWindow()
 {
     textEdit = new QTextEdit;
     setCentralWidget(textEdit);

     createActions();
     createMenus();
     createToolBars();
     createStatusBar();

     readSettings();

     connect(textEdit-&gt;document(), SIGNAL(contentsChanged()),
             this, SLOT(documentWasModified()));

     setCurrentFile(&quot;&quot;);
 }</pre>
<p>In the constructor, we start by creating a <a href="qtextedit.html">QTextEdit</a> widget as a child of the main window (the <tt>this</tt> object). Then we call <a href="qmainwindow.html#setCentralWidget">QMainWindow::setCentralWidget</a>() to tell that this is going to be the widget that occupies the central area of the main window, between the toolbars and the status bar.</p>
<p>Then we call <tt>createActions()</tt>, <tt>createMenus()</tt>, <tt>createToolBars()</tt>, and <tt>createStatusBar()</tt>, four private functions that set up the user interface. After that, we call <tt>readSettings()</tt> to restore the user's preferences.</p>
<p>We establish a signal-slot connection between the <a href="qtextedit.html">QTextEdit</a>'s document object and our <tt>documentWasModified()</tt> slot. Whenever the user modifies the text in the <a href="qtextedit.html">QTextEdit</a>, we want to update the title bar to show that the file was modified.</p>
<p>At the end, we set the window title using the private <tt>setCurrentFile()</tt> function. We'll come back to this later.</p>
<a name="close-event-handler"></a><pre> void MainWindow::closeEvent(QCloseEvent *event)
 {
     if (maybeSave()) {
         writeSettings();
         event-&gt;accept();
     } else {
         event-&gt;ignore();
     }
 }</pre>
<p>When the user attempts to close the window, we call the private function <tt>maybeSave()</tt> to give the user the possibility to save pending changes. The function returns true if the user wants the application to close; otherwise, it returns false. In the first case, we save the user's preferences to disk and accept the close event; in the second case, we ignore the close event, meaning that the application will stay up and running as if nothing happened.</p>
<pre> void MainWindow::newFile()
 {
     if (maybeSave()) {
         textEdit-&gt;clear();
         setCurrentFile(&quot;&quot;);
     }
 }</pre>
<p>The <tt>newFile()</tt> slot is invoked when the user selects <b>File|New</b> from the menu. We call <tt>maybeSave()</tt> to save any pending changes and if the user accepts to go on, we clear the <a href="qtextedit.html">QTextEdit</a> and call the private function <tt>setCurrentFile()</tt> to update the window title and clear the <a href="qwidget.html#windowModified-prop">windowModified</a> flag.</p>
<pre> void MainWindow::open()
 {
     if (maybeSave()) {
         QString fileName = QFileDialog::getOpenFileName(this);
         if (!fileName.isEmpty())
             loadFile(fileName);
     }
 }</pre>
<p>The <tt>open()</tt> slot is invoked when the user clicks <b>File|Open</b>. We pop up a <a href="qfiledialog.html">QFileDialog</a> asking the user to choose a file. If the user chooses a file (i.e&#x2e;, <tt>fileName</tt> is not an empty string), we call the private function <tt>loadFile()</tt> to actually load the file.</p>
<pre> bool MainWindow::save()
 {
     if (curFile.isEmpty()) {
         return saveAs();
     } else {
         return saveFile(curFile);
     }
 }</pre>
<p>The <tt>save()</tt> slot is invoked when the user clicks <b>File|Save</b>. If the user hasn't provided a name for the file yet, we call <tt>saveAs()</tt>; otherwise, we call the private function <tt>saveFile()</tt> to actually save the file.</p>
<pre> bool MainWindow::saveAs()
 {
     QString fileName = QFileDialog::getSaveFileName(this);
     if (fileName.isEmpty())
         return false;

     return saveFile(fileName);
 }</pre>
<p>In <tt>saveAs()</tt>, we start by popping up a <a href="qfiledialog.html">QFileDialog</a> asking the user to provide a name. If the user clicks <b>Cancel</b>, the returned file name is empty, and we do nothing.</p>
<pre> void MainWindow::about()
 {
    QMessageBox::about(this, tr(&quot;About Application&quot;),
             tr(&quot;The &lt;b&gt;Application&lt;/b&gt; example demonstrates how to &quot;
                &quot;write modern GUI applications using Qt, with a menu bar, &quot;
                &quot;toolbars, and a status bar.&quot;));
 }</pre>
<p>The application's About box is done using one statement, using the <a href="qmessagebox.html#about">QMessageBox::about</a>() static function and relying on its support for an HTML subset.</p>
<p>The <a href="qobject.html#tr">tr()</a> call around the literal string marks the string for translation. It is a good habit to call <a href="qobject.html#tr">tr()</a> on all user-visible strings, in case you later decide to translate your application to other languages. The <a href="i18n.html">Internationalization with Qt</a> overview convers <a href="qobject.html#tr">tr()</a> in more detail.</p>
<pre> void MainWindow::documentWasModified()
 {
     setWindowModified(textEdit-&gt;document()-&gt;isModified());
 }</pre>
<p>The <tt>documentWasModified()</tt> slot is invoked each time the text in the <a href="qtextedit.html">QTextEdit</a> changes because of user edits. We call <a href="qwidget.html#windowModified-prop">QWidget::setWindowModified</a>() to make the title bar show that the file was modified. How this is done varies on each platform.</p>
<pre> void MainWindow::createActions()
 {
     newAct = new QAction(QIcon(&quot;:/images/new.png&quot;), tr(&quot;&amp;New&quot;), this);
     newAct-&gt;setShortcut(tr(&quot;Ctrl+N&quot;));
     newAct-&gt;setStatusTip(tr(&quot;Create a new file&quot;));
     connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));

     openAct = new QAction(QIcon(&quot;:/images/open.png&quot;), tr(&quot;&amp;Open...&quot;), this);
     openAct-&gt;setShortcut(tr(&quot;Ctrl+O&quot;));
     openAct-&gt;setStatusTip(tr(&quot;Open an existing file&quot;));
     connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
     ...
     aboutQtAct = new QAction(tr(&quot;About &amp;Qt&quot;), this);
     aboutQtAct-&gt;setStatusTip(tr(&quot;Show the Qt library's About box&quot;));
     connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));</pre>
<p>The <tt>createActions()</tt> private function, which is called from the <tt>MainWindow</tt> constructor, creates <a href="qaction.html">QAction</a>s. The code is very repetitive, so we show only the actions corresponding to <b>File|New</b>, <b>File|Open</b>, and <b>Help|About Qt</b>.</p>
<p>A <a href="qaction.html">QAction</a> is an object that represents one user action, such as saving a file or invoking a dialog. An action can be put in a <a href="qmenu.html">QMenu</a> or a <a href="qtoolbar.html">QToolBar</a>, or both, or in any other widget that reimplements <a href="qwidget.html#actionEvent">QWidget::actionEvent</a>().</p>
<p>An action has a text that is shown in the menu, an icon, a shortcut key, a tooltip, a status tip (shown in the status bar), a &quot;What's This?&quot; text, and more. It emits a <a href="qaction.html#triggered">triggered()</a> signal whenever the user invokes the action (e.g&#x2e;, by clicking the associated menu item or toolbar button). We connect this signal to a slot that performs the actual action.</p>
<p>The code above contains one more idiom that must be explained. For some of the actions, we specify an icon as a <a href="qicon.html">QIcon</a> to the <a href="qaction.html">QAction</a> constructor. The <a href="qicon.html">QIcon</a> constructor takes the file name of an image that it tries to load. Here, the file name starts with <tt>:</tt>. Such file names aren't ordinary file names, but rather path in the executable's stored resources. We'll come back to this when we review the <tt>application.qrc</tt> file that's part of the project.</p>
<pre>     cutAct-&gt;setEnabled(false);
     copyAct-&gt;setEnabled(false);
     connect(textEdit, SIGNAL(copyAvailable(bool)),
             cutAct, SLOT(setEnabled(bool)));
     connect(textEdit, SIGNAL(copyAvailable(bool)),
             copyAct, SLOT(setEnabled(bool)));
 }</pre>
<p>The <b>Edit|Cut</b> and <b>Edit|Copy</b> actions must be available only when the <a href="qtextedit.html">QTextEdit</a> contains selected text. We disable them by default and connect the <a href="qtextedit.html#copyAvailable">QTextEdit::copyAvailable</a>() signal to the <a href="qaction.html#enabled-prop">QAction::setEnabled</a>() slot, ensuring that the actions are disabled when the text editor has no selection.</p>
<pre> void MainWindow::createMenus()
 {
     fileMenu = menuBar()-&gt;addMenu(tr(&quot;&amp;File&quot;));
     fileMenu-&gt;addAction(newAct);
     fileMenu-&gt;addAction(openAct);
     fileMenu-&gt;addAction(saveAct);
     fileMenu-&gt;addAction(saveAsAct);
     fileMenu-&gt;addSeparator();
     fileMenu-&gt;addAction(exitAct);

     editMenu = menuBar()-&gt;addMenu(tr(&quot;&amp;Edit&quot;));
     editMenu-&gt;addAction(cutAct);
     editMenu-&gt;addAction(copyAct);
     editMenu-&gt;addAction(pasteAct);

     menuBar()-&gt;addSeparator();

     helpMenu = menuBar()-&gt;addMenu(tr(&quot;&amp;Help&quot;));
     helpMenu-&gt;addAction(aboutAct);
     helpMenu-&gt;addAction(aboutQtAct);
 }</pre>
<p>Creating actions isn't sufficient to make them available to the user; we must also add them to the menu system. This is what <tt>createMenus()</tt> does. We create a <b>File</b>, an <b>Edit</b>, and a <b>Help</b> menu. <a href="qmainwindow.html#menuBar">QMainWindow::menuBar</a>() lets us access the window's menu bar widget. We don't have to worry about creating the menu bar ourselves; the first time we call this function, the <a href="qmenubar.html">QMenuBar</a> is created.</p>
<p>Just before we create the <b>Help</b> menu, we call <a href="qmenubar.html#addSeparator">QMenuBar::addSeparator</a>(). This has no effect for most widget styles (e.g&#x2e;, Windows and Mac OS X styles), but for Motif-based styles this makes sure that <b>Help</b> is pushed to the right side of the menu bar. Try running the application with various styles and see the results:</p>
<pre> application -style=windows
 application -style=motif
 application -style=cde</pre>
<p>Let's now review the toolbars:</p>
<pre> void MainWindow::createToolBars()
 {
     fileToolBar = addToolBar(tr(&quot;File&quot;));
     fileToolBar-&gt;addAction(newAct);
     fileToolBar-&gt;addAction(openAct);
     fileToolBar-&gt;addAction(saveAct);

     editToolBar = addToolBar(tr(&quot;Edit&quot;));
     editToolBar-&gt;addAction(cutAct);
     editToolBar-&gt;addAction(copyAct);
     editToolBar-&gt;addAction(pasteAct);
 }</pre>
<p>Creating toolbars is very similar to creating menus. The same actions that we put in the menus can be reused in the toolbars.</p>
<pre> void MainWindow::createStatusBar()
 {
     statusBar()-&gt;showMessage(tr(&quot;Ready&quot;));
 }</pre>
<p><a href="qmainwindow.html#statusBar">QMainWindow::statusBar</a>() returns a pointer to the main window's <a href="qstatusbar.html">QStatusBar</a> widget. Like with <a href="qmainwindow.html#menuBar">QMainWindow::menuBar</a>(), the widget is automatically created the first time the function is called.</p>
<pre> void MainWindow::readSettings()
 {
     QSettings settings(&quot;Trolltech&quot;, &quot;Application Example&quot;);
     QPoint pos = settings.value(&quot;pos&quot;, QPoint(200, 200)).toPoint();
     QSize size = settings.value(&quot;size&quot;, QSize(400, 400)).toSize();
     resize(size);
     move(pos);
 }</pre>
<p>The <tt>readSettings()</tt> function is called from the constructor to load the user's preferences and other application settings. The <a href="qsettings.html">QSettings</a> class provides a high-level interface for storing settings permanently on disk. On Windows, it uses the (in)famous Windows registry; on Mac OS X, it uses the native XML-based CFPreferences API; on Unix/X11, it uses text files.</p>
<p>The <a href="qsettings.html">QSettings</a> constructor takes arguments that identify your company and the name of the product. This ensures that the settings for different applications are kept separately.</p>
<p>We use <a href="qsettings.html#value">QSettings::value</a>() to extract the value of the &quot;pos&quot; and &quot;size&quot; settings. The second argument to <a href="qsettings.html#value">QSettings::value</a>() is optional and specifies a default value for the setting if there exists none. This value is used the first time the application is run.</p>
<p>When restoring the position and size of a window, it's important to call <a href="qwidget.html#size-prop">QWidget::resize</a>() before <a href="qwidget.html#pos-prop">QWidget::move</a>(). The reason why is given in the <a href="geometry.html">Window Geometry</a> overview.</p>
<pre> void MainWindow::writeSettings()
 {
     QSettings settings(&quot;Trolltech&quot;, &quot;Application Example&quot;);
     settings.setValue(&quot;pos&quot;, pos());
     settings.setValue(&quot;size&quot;, size());
 }</pre>
<p>The <tt>writeSettings()</tt> function is called from <tt>closeEvent()</tt>. Writing settings is similar to reading them, except simpler. The arguments to the <a href="qsettings.html">QSettings</a> constructor must be the same as in <tt>readSettings()</tt>.</p>
<pre> bool MainWindow::maybeSave()
 {
     if (textEdit-&gt;document()-&gt;isModified()) {
         QMessageBox::StandardButton ret;
         ret = QMessageBox::warning(this, tr(&quot;Application&quot;),
                      tr(&quot;The document has been modified.\n&quot;
                         &quot;Do you want to save your changes?&quot;),
                      QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
         if (ret == QMessageBox::Save)
             return save();
         else if (ret == QMessageBox::Cancel)
             return false;
     }
     return true;
 }</pre>
<p>The <tt>maybeSave()</tt> function is called to save pending changes. If there are pending changes, it pops up a <a href="qmessagebox.html">QMessageBox</a> giving the user to save the document. The options are <a href="qmessagebox.html#StandardButton-enum">QMessageBox::Yes</a>, <a href="qmessagebox.html#StandardButton-enum">QMessageBox::No</a>, and <a href="qmessagebox.html#StandardButton-enum">QMessageBox::Cancel</a>. The <b>Yes</b> button is made the default button (the button that is invoked when the user presses <b>Return</b>) using the <a href="qmessagebox.html#StandardButton-enum">QMessageBox::Default</a> flag; the <b>Cancel</b> button is made the escape button (the button that is invoked when the user presses <b>Esc</b>) using the <a href="qmessagebox.html#StandardButton-enum">QMessageBox::Escape</a> flag.</p>
<p>The <tt>maybeSave()</tt> function returns <tt>true</tt> in all cases, except when the user clicks <b>Cancel</b>. The caller must check the return value and stop whatever it was doing if the return value is <tt>false</tt>.</p>
<pre> void MainWindow::loadFile(const QString &amp;fileName)
 {
     QFile file(fileName);
     if (!file.open(QFile::ReadOnly | QFile::Text)) {
         QMessageBox::warning(this, tr(&quot;Application&quot;),
                              tr(&quot;Cannot read file %1:\n%2.&quot;)
                              .arg(fileName)
                              .arg(file.errorString()));
         return;
     }

     QTextStream in(&amp;file);
     QApplication::setOverrideCursor(Qt::WaitCursor);
     textEdit-&gt;setPlainText(in.readAll());
     QApplication::restoreOverrideCursor();

     setCurrentFile(fileName);
     statusBar()-&gt;showMessage(tr(&quot;File loaded&quot;), 2000);
 }</pre>
<p>In <tt>loadFile()</tt>, we use <a href="qfile.html">QFile</a> and <a href="qtextstream.html">QTextStream</a> to read in the data. The <a href="qfile.html">QFile</a> object provides access to the bytes stored in a file.</p>
<p>We start by opening the file in read-only mode. The <a href="qiodevice.html#OpenModeFlag-enum">QFile::Text</a> flag indicates that the file is a text file, not a binary file. On Unix and Mac OS X, this makes no difference, but on Windows, it ensures that the &quot;\r\n&quot; end-of-line sequence is converted to &quot;\n&quot; when reading.</p>
<p>If we successfully opened the file, we use a <a href="qtextstream.html">QTextStream</a> object to read in the data. <a href="qtextstream.html">QTextStream</a> automatically converts the 8-bit data into a Unicode <a href="qstring.html">QString</a> and supports various encodings. If no encoding is specified, <a href="qtextstream.html">QTextStream</a> assumes the file is written using the system's default 8-bit encoding (for example, Latin-1; see <a href="qtextcodec.html#codecForLocale">QTextCodec::codecForLocale</a>() for details).</p>
<p>Since the call to <a href="qtextstream.html#readAll">QTextStream::readAll</a>() might take some time, we set the cursor to be <a href="qt.html#CursorShape-enum">Qt::WaitCursor</a> for the entire application while it goes on.</p>
<p>At the end, we call the private <tt>setCurrentFile()</tt> function, which we'll cover in a moment, and we display the string &quot;File loaded&quot; in the status bar for 2 seconds (2000 milliseconds).</p>
<pre> bool MainWindow::saveFile(const QString &amp;fileName)
 {
     QFile file(fileName);
     if (!file.open(QFile::WriteOnly | QFile::Text)) {
         QMessageBox::warning(this, tr(&quot;Application&quot;),
                              tr(&quot;Cannot write file %1:\n%2.&quot;)
                              .arg(fileName)
                              .arg(file.errorString()));
         return false;
     }

     QTextStream out(&amp;file);
     QApplication::setOverrideCursor(Qt::WaitCursor);
     out &lt;&lt; textEdit-&gt;toPlainText();
     QApplication::restoreOverrideCursor();

     setCurrentFile(fileName);
     statusBar()-&gt;showMessage(tr(&quot;File saved&quot;), 2000);
     return true;
 }</pre>
<p>Saving a file is very similar to loading one. Here, the <a href="qiodevice.html#OpenModeFlag-enum">QFile::Text</a> flag ensures that on Windows, &quot;\n&quot; is converted into &quot;\r\n&quot; to conform to the Windows convension.</p>
<pre> void MainWindow::setCurrentFile(const QString &amp;fileName)
 {
     curFile = fileName;
     textEdit-&gt;document()-&gt;setModified(false);
     setWindowModified(false);

     QString shownName;
     if (curFile.isEmpty())
         shownName = &quot;untitled.txt&quot;;
     else
         shownName = strippedName(curFile);

     setWindowTitle(tr(&quot;%1[*] - %2&quot;).arg(shownName).arg(tr(&quot;Application&quot;)));
 }</pre>
<p>The <tt>setCurrentFile()</tt> function is called to reset the state of a few variables when a file is loaded or saved, or when the user starts editing a new file (in which case <tt>fileName</tt> is empty). We update the <tt>curFile</tt> variable, clear the <a href="qtextdocument.html#modified-prop">QTextDocument::modified</a> flag and the associated <tt>QWidget:windowModified</tt> flag, and update the window title to contain the new file name (or <tt>untitled.txt</tt>).</p>
<p>The <tt>strippedName()</tt> function call around <tt>curFile</tt> in the <a href="qwidget.html#windowTitle-prop">QWidget::setWindowTitle</a>() call shortens the file name to exclude the path. Here's the function:</p>
<pre> QString MainWindow::strippedName(const QString &amp;fullFileName)
 {
     return QFileInfo(fullFileName).fileName();
 }</pre>
<a name="the-main-function"></a>
<h2>The main() Function</h2>
<p>The <tt>main()</tt> function for this application is typical of applications that contain one main window:</p>
<pre> #include &lt;QApplication&gt;

 #include &quot;mainwindow.h&quot;

 int main(int argc, char *argv[])
 {
     Q_INIT_RESOURCE(application);

     QApplication app(argc, argv);
     MainWindow mainWin;
     mainWin.show();
     return app.exec();
 }</pre>
<a name="the-resource-file"></a>
<h2>The Resource File</h2>
<p>As you will probably recall, for some of the actions, we specified icons with file names starting with <tt>:</tt> and mentioned that such file names aren't ordinary file names, but path in the executable's stored resources. These resources are compiled</p>
<p>The resources associated with an application are specified in a <tt>.qrc</tt> file, an XML-based file format that lists files on the disk. Here's the <tt>application.qrc</tt> file that's used by the Application example:</p>
<pre> &lt;!DOCTYPE RCC&gt;&lt;RCC version=&quot;1.0&quot;&gt;
 &lt;qresource&gt;
     &lt;file&gt;images/copy.png&lt;/file&gt;
     &lt;file&gt;images/cut.png&lt;/file&gt;
     &lt;file&gt;images/new.png&lt;/file&gt;
     &lt;file&gt;images/open.png&lt;/file&gt;
     &lt;file&gt;images/paste.png&lt;/file&gt;
     &lt;file&gt;images/save.png&lt;/file&gt;
 &lt;/qresource&gt;
 &lt;/RCC&gt;</pre>
<p>The <tt>.png</tt> files listed in the <tt>application.qrc</tt> file are files that are part of the Application example's source tree. Paths are relative to the directory where the <tt>application.qrc</tt> file is located (the <tt>mainwindows/application</tt> directory).</p>
<p>The resource file must be mentioned in the <tt>application.pro</tt> file so that <tt>qmake</tt> knows about it:</p>
<pre> RESOURCES     = application.qrc</pre>
<p><tt>qmake</tt> will produce make rules to generate a file called <tt>qrc_application.cpp</tt> that is linked into the application. This file contains all the data for the images and other resources as static C++ arrays of compressed binary data. See <a href="resources.html">The Qt Resource System</a> for more information about resources.</p>
<p /><address><hr /><div align="center">
<table width="100%" cellspacing="0" border="0"><tr class="address">
<td width="30%">Copyright &copy; 2008 <a href="trolltech.html">Trolltech</a></td>
<td width="40%" align="center"><a href="trademarks.html">Trademarks</a></td>
<td width="30%" align="right"><div align="right">Qt 4.3.5</div></td>
</tr></table></div></address></body>
</html>
